#ifndef __OS_DEFS_H__
#define __OS_DEFS_H__

/* os_defs.h:
 * global definition 
 *
 * (C) Copyright 2013 Ramone de Castillon 
 * ramone.castillon@gmail.com
 * http://poker-botting.blogspot.fr/.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */


#include "std_inc.h"

/***********************************
 * constants
 ***********************************/

/* version of this file. to be checked  when receiving os_frame struct */
#define OS_INTF_VERSION 7  
#define OS_MAX_PLAYERS 10   /* maximum number of players */
#define OS_NB_HANDS 	1326
#define OS_CARD_NONE 	255  /* each card have a value between 0 to 63 */
#define OS_NB_CARDS 52
#define OS_STR_MAX 64
#define OS_TEXT_MAX 256
#define OS_MAX_PATH 128
#define OS_MAX_FILELINE 256
#define OS_HO_FILE_VERSION 3 /* hand generated file version */

/* button */
#define OS_BT_DEALER 1
#define OS_BT_SBLIND 2
#define OS_BT_BBLIND 4
#define OS_BT_NONE   8
#define OS_BT_OUT    16

/* round name */
#define OS_RD_UNDEF   0
#define OS_RD_PREFLOP 1
#define OS_RD_FLOP    2
#define OS_RD_TURN    3
#define OS_RD_RIVER   4
#define OS_RD_END     5

/* game type */
#define OS_GT_CASH 	 0
#define OS_GT_TOURNAMENT 1

static inline const char *betround_tostr(int betround)
{
	switch(betround) {
		case OS_RD_PREFLOP:
			return "preflop";
		case OS_RD_FLOP:
			return "flop";
		case OS_RD_TURN:
			return "turn";
		case OS_RD_RIVER:
			return "river";
		case OS_RD_END:
			return "end";
		case OS_RD_UNDEF:
		default:
			return "error";
	};
}


/***********************************
 * actions
 ***********************************/

/* os_action */
#define OS_ACT_LEAVE  -1 /* stop to play */
#define OS_ACT_FOLD   -2 /* fold this hand */
#define OS_ACT_ALLIN  -3 /* go all-in */
#define OS_ACT_NONE   -7 /* no action */
#define OS_ACT_ERROR  -8 /* error (like os_game version mismatch */
#define OS_ACT_CHECK  0  /* FIXME */
#define OS_ACT_MAX    0  /* FIXME */

/* special action */
#define OS_ACT_CALL  -4
#define OS_ACT_BET   -5
#define OS_ACT_RAISE -6
#define OS_ACT_RERAISE -9

static inline const char *action_to_str(int decision, char str[8]) {
	switch (decision) {
		case OS_ACT_LEAVE:
			return "leave";
		case OS_ACT_FOLD:
			return "fold";
		case OS_ACT_ALLIN:
			return "allin";
		case OS_ACT_NONE:
			return "do nothing";
		case OS_ACT_ERROR:
			return "action error";
		case OS_ACT_CHECK:
			return "check";
		case OS_ACT_CALL:
			return "call";
	};

	if (decision > 0) {
		//static __thread char str[32];
		snprintf(str, sizeof(str)-1, "%d", decision);
		return str;
	}

	return "undefined action";
}

/***********************************
 * players
 ***********************************/

struct os_player{
	int32_t cash;		/* player cash */
	int32_t bet;		/* */
	int32_t totalbet;	/* */
	int32_t action;		/* action like OS_ACT_FOLD */
	int8_t button;		/* OS_BT_SBLIND etc ... */
	uint8_t id;		/* player uniq id from 0 to 9 */
#define FL_PLAYER_AGRP 1	/* aggressive player. FIXME: remove me*/
#define FL_PLAYER_AGRF 2
#define FL_PLAYER_AGRT 4
#define FL_PLAYER_AGRR 8
#define FL_PLAYER_AGR_AFTERFLOP (FL_PLAYER_AGRF|FL_PLAYER_AGRT|FL_PLAYER_AGRR)
	int16_t flags;		/* private flags to use with your bot */
	uint8_t cards[2];	/* player cards. see cards format below */
	uint16_t _pad;		
#define MAX_STR_NAME 32
	char name[MAX_STR_NAME];/* player name */
	void *priv;		/* private data reserved for ia */
	void *hpriv;		/* private data reserved for main application */
	struct os_player *next;
	struct os_game *g;
}__attribute__((packed));


/***********************************
 * game
 ***********************************/

struct os_game {
	uint8_t os_version;	/* check that this value equal to OS_INTF_VERSION */
	uint8_t nplayers;	/* number of players */
	uint8_t naplayers;	/* number of active players */
//	int ismyturn;
	uint8_t playeridturn;	/* id of the player whose it's his turn */
	uint8_t userchair;	/* your id number */
	uint8_t dealerchair;	/* id of the dealer */
	uint16_t nhands;

	uint32_t nframes;	/* incremented every time we got a new image of the poker table */
	uint8_t betround;	/* OS_RD_PREFLOP, etc ... */
	uint8_t betround_turn;	/* when someone raise, we have play an another turn */ 
	uint16_t _pad;		/* and betround_turn is increased */
	
	int32_t pot;		/* pot value */
	int32_t bets;		/* */
	int32_t sblind;		/* small blind value */
	int32_t bblind;		/* */
	//int32_t fblind;		/* bblind = sblind*fblind*/
	int32_t ante;		/* ante value */
	int32_t highestset;	/* */
	int32_t call; 		/*amount to call */

	uint8_t cards[5];	/* board cards */
	uint8_t _pad2[3];

	void *priv;
	int privsize;
	int privbroken;		/* internal, used by historic loader. (set to 1 if pointer in priv is broken) */
	void *histo;
	
	struct os_player players[OS_MAX_PLAYERS];
}__attribute__((packed));

/***********************************
 * cards
 ***********************************/

/* cards format:
 * the number is defined as uint8_t and can be between 0 to 51.
 * OS_CARD_NONE is a special number, used when we don't know the card
 * 
 * to get the card color and the card value from the number, you have
 * compute it like this;
 * card_color = card/13; (0=diamond, 1=heart, 2=spade, 3=club)
 * card_value = card%13; (0=card num°2, ..., 10=jack, ... 13=As) 
 */

#define OS_CARD_NONE 255



#endif /* __OS_DEFS_H__ */

